Ext.ns('TaxonTagger');
TaxonTagger.NameGrid = function(config, id) {

	this.urlCombo = new Ext.form.ComboBox({
			store: {
					xtype: 'arraystore'
				,	fields: ['url']
			}
		,	displayField: 'url'
		,	scope: this
		,	typeAhead: true
		,	mode: 'local'
		,	triggerAction: 'all'
		,	emptyText: this.txtEmptyUrlCombo
		,	selectOnFocus: true
		,	allowBlank: false
		,	blankText: this.txtBlankUrlCombo
		,	vtype: 'url'
		,	urlText: this.txtUrlCombo
		,	width: 300
	});
	
	var urlList = Ext.decode(localStorage.getItem("storedUrls")) || '';
	this.urlCombo.store.loadData(Ext.zip(urlList), true);
	 
	this.btnClassify = new Ext.Button({
			text: this.txtClassifyBtn
		,	scope: this
		,	hidden: true
		,	iconCls: 'icon_mark'
		,	tooltip: this.txtClassifyBtnTip
		,	handler: this.classify
	});

	this.task = new Ext.util.DelayedTask(function(){
		this.getBottomToolbar().clearStatus();
		this.getBottomToolbar().setText(this.bbarClassifyTxt);
		this.btnClassify.enable(); 
	}, this);
	
	this.primaryCombo = new Ext.form.ComboBox({
			store: TaxonTagger.authorityStore
		,	displayField: 'authority'
		,	scope: this
		,	qtip: this.txtPrimaryComboTip
		,	valueField: 'id'
		,	hidden: true
		,	editable: false
		,	typeAhead: true
		,	mode: 'local'
		,	triggerAction: 'all'
		,	selectOnFocus: true
		,	listeners: {
				render: function(c){
					c.el.set({qtip:c.qtip});
				}
			}
	});
 
	this.secondaryCombo = new Ext.form.ComboBox({
			store: TaxonTagger.authorityStore
		,	displayField: 'authority'
		,	scope: this
		,	qtip: this.txtSecondaryComboTip
		,	valueField: 'id'
		,	hidden: true
		,	editable: false
		,	typeAhead: true
		,	mode: 'local'
		,	triggerAction: 'all'
		,	selectOnFocus: true
		,	listeners: {
				render :function(c){
					c.el.set({qtip:c.qtip});
				}
			}
	});


	
	Ext.apply(this, config, {
			store: TaxonTagger.docStore		
		,	id: 'nubPanel'
		,	iconCls:'icon_table'
		,	columns: [
					{header: "GBIF Ref. ID", width: 75, sortable: true, dataIndex: 'taxonID'}
				,	{header: "Scientific Name", width: 180, sortable: true, dataIndex: 'scientificName'}
				,	{header: "Genus", width: 95, sortable: true, dataIndex: 'genus'}
				,	{header: "Family", width: 95, sortable: true, dataIndex: 'family'}
				,	{header: "Class", width: 80, sortable: true, dataIndex: 'class_'}
				,	{header: "Order", width: 85, sortable: true, dataIndex: 'order'}
				,	{header: "Phylum", width: 70, sortable: true, dataIndex: 'phylum'}
				,	{header: "Kingdom", width: 65, sortable: true, dataIndex: 'kingdom'}
				,	{header: "Synonym", width: 65, sortable: true, dataIndex: 'isSynonym', renderer: this.renderregion}
				,	{header: "Accepted Name Usage", width: 120, sortable: true, dataIndex: 'acceptedName'}
				,	{header: "Name According To", width: 105, sortable: true, dataIndex: 'accordingTo'}
			]
		,	view: new Ext.grid.GridView({
					forceFit: false
				,	emptyText: this.txtEmptyView
				,	deferEmptyText: false
			})
		,	tbar: [
					this.txtUrl
				,	this.urlCombo
				, '&nbsp;', {
							text: this.txtLoadBtn
						,	iconCls: 'icon_load'	
						,	scope: this 
						,	tooltip: this.txtLoadBtnTip
						,	handler: this.loadDocument
				}, '&nbsp;'
					,	this.btnClassify
					,	'->'
					,	this.primaryCombo
					,	'&nbsp;'
					,	'&nbsp;'
					,	this.secondaryCombo
			]
		,	sm: new Ext.grid.RowSelectionModel({singleSelect: true})
		,	border: false
		,	loadMask: {msg: this.msgLoadMask}
		,	autoScroll: true
		,	loadedList: false
		,	defaults: {
				border: false
			}
		,	lastClassified: ''
		,	lastClassfiedUrl: ''
		,	lasturlLoaded: ''
		,	newAdded: false
		,	tools: [{
					id: 'right'
				,	scope: this
				,	qtip: this.toolsTxt
				,	handler: function() {
						this.fireEvent("switchView", "documentMode", this);
					}
			}]		
		,	bbar: new Ext.ux.StatusBar({ 
					statusAlign: 'right'
				,	scope: this
				,	defaultText: '&nbsp;'					
			})
		,	listeners: {
					rowdblclick: function(grid, rowIndex, e){
						var id = grid.getStore().getAt(rowIndex).get('taxonID');
						if(Ext.isEmpty(id)){
							TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgNoGbifId)
						}else {
							window.open('http://ecat-dev.gbif.org/usage/' + id, '_blank');
						}
					}
				,	rowcontextmenu: this.showContextMenu
			}
	});

	TaxonTagger.NameGrid.superclass.constructor.call(this, config);

};

Ext.extend(TaxonTagger.NameGrid, Ext.grid.GridPanel, {

		renderregion: function(qty, dom, row, index) {
			if (qty == true) {
				return('<div class="region_notempty"></div>');
			} else {
				return('<div class="region_empty" />');
			}
		}

	,	showContextMenu: function(grid, row, e){
			grid.getSelectionModel().selectRow(row);
			var record = grid.getSelectionModel().getSelected().data;
			var items = [];
			var item1 = ({
					text: this.txtGBIFChecklistBank
				,	ref: 'checkBank'
				,	iconCls: 'icon_gbif'
				,	scope: this	
				,	handler: function() {
							window.open('http://ecat-dev.gbif.org/search?q=' + record.scientificName + '&rkey=1', '_blank');
					}  
			});
			var item2 = ({
					text: this.txtEditCommment
				,	iconCls: 'icon_comments'
				,	scope: this
				,	handler: function() {
						this.showComment(grid, row);
					}
			});
			var item3 = ({
					text: this.txtClassifyBtn
				,	scope: this
				,	iconCls: 'icon_mark'
				,	handler: function() {
						this.lookupSingleRow(grid, row);
					}
			});
			var item4 = ({
					text: this.txtRemoveName
				,	iconCls: 'icon_delete'	
				,	scope: this
				,	handler: function() {
						var selected = this.getSelectionModel().getSelected().data;
						var index = TaxonTagger.docStore.findExact('scientificName', selected.scientificName);
						TaxonTagger.docStore.removeAt(index);
						if(TaxonTagger.docStore.getCount() == 0){
							Ext.getCmp('tools').disableChild();
							Ext.getCmp('tools').clearEnableDisable();
						}
					}
			})
			var item5 = ({
					text: this.txtTaxamatch
				,	scope: this	
				,	handler: function() { 
						this.showTaxaMatch(grid, row);
					}  	
			})
			items.push(item1);
			if(Config.currerntService == "TaxonTagger" ){
				items.push(item2);
			}
			items.push(item3);
			if(Config.currerntService != "TaxonTagger" ){
				items.push(item4);
			}
			if((record.taxonID == '' && this.lastClassified != '') && Config.useTaxamatch){
				items.push(item5);
			}
			var menu = new Ext.menu.Menu({
					items: items
			});
			var xy = e.getXY();
			menu.showAt(xy);
		}

	,	showComment: function(grid, row){
			var data = this.store.getAt(row).data;
			this.comments = new TaxonTagger.comments({
					title: this.titleShowComment + data.scientificName
				,	keyName: data.scientificName
				,	scope: this
			});
			this.comments.loadComment();
			this.comments.on("close", this.updateComment, this);
			this.comments.show();
		}

	,	showTaxaMatch: function(grid, row){
			var data = this.store.getAt(row).data;
			this.taxamatch = new TaxonTagger.TaxamatchLookup({
						title: this.titleShowTaxamatch +'(' + data.verbatim + ')'
					,	keyName: data.verbatim	
				});
			this.taxamatch.txtSearch.setValue(data.verbatim);		
			this.taxamatch.show();
		}
		
	,	classify: function(){
			var url = this.urlCombo.getValue();
			if (this.store.getCount() == 0){
				TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgClassifyNotice);
			} else {
				this.btnClassify.disable();
				if(this.lastClassified != this.primaryCombo.getValue() || this.lastClassfiedUrl != url){
					this.prepareClassify();
				}else {
					if(this.newAdded){
						TaxonTagger.docStore.each(function(item){
								if(!item.data.processed){
									var index = TaxonTagger.docStore.indexOf(item);
									this.lookupSingleRow(this, index);
								}
						},this);
						this.newAdded = false;
					}else {
						TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgAlreadyClassified);
					}
				}
				this.lastClassified = this.primaryCombo.getValue();
				this.getBottomToolbar().showBusy();
				var connCt = 4;
				this.lastClassfiedUrl = url;
				for (var i=0; i < connCt; i++){
					this.lookupRow(i);
				}
			}
		}

	,	prepareClassify: function(){
			TaxonTagger.docStore.each(function(rec){
				rec.set('processed', false);
			}, this);
		}	
		
	,	addNewSciName: function(list){
			var list = list.slice();
			for (var i =0; i < list.length; i++){
				var found = this.store.find('scientificName',list[i]);
				if(found == -1){
					this.store.loadData([{
							scientificName: list[i]
						,	found: false
						,	processed: false	
					}], true);
					this.store.sort('scientificName', 'ASC');
				}
			}
			this.loadMask.hide();
		}

	,	removeSciName: function(list){
			var list = list.slice();
			this.store.each(function(item){
				var found = true;
				for (var i =0; i < list.length; i++){
					if (item.data.scientificName == list[i]){
						found = true;
						break;
					} else {
						found = false;
					}
				}
				if(!found){
					var index = this.store.indexOf(item);
					this.store.removeAt(index);
				}
			}, this);
			this.loadMask.hide();
		}

	,	isURL: function(s) {
			var regexp = /http:\/\/[A-Za-z0-9\.-]{3,}\.[A-Za-z]{3}/;
			return regexp.test(s);
		}

	,	loadDocument: function(){
			var url = this.urlCombo.getValue();
			if (Ext.isEmpty(url)) {
				TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgEmptyLoadDoc);
			}else if (!this.isURL(url)) {
				TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgValidLoadDoc);
			} else if(this.lasturlLoaded == url){
				this.loadMask.hide();
				TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgAlreadyLoadedDoc);
			} else {
				this.loadMask.show();
				this.store.removeAll();
				this.loadedList = false;
				this.lasturlLoaded = url;
				this.fireEvent('urlLoaded', this.urlCombo.getValue(),this);
				this.getBottomToolbar().clearStatus();
				this.getBottomToolbar().setText(this.bbarTxt);
			}
		}

	,	showChild: function(){
			this.btnClassify.show();
			this.primaryCombo.show();
			this.secondaryCombo.show();
		}

	,	lookupSingleRow: function(grid,index){
			var data = this.store.getAt(index).data;
			data.processed = true;
			Ext.Ajax.request({
					scope: this
				,	url: 'resources/api/get.php'
				,	params: {
							name: data.scientificName
						,	cmd: 'taxagrid'
						,	rkey: this.primaryCombo.getValue()
						,	skey: this.secondaryCombo.getValue()
					}
				,	success: function(response){
						var response = Ext.decode(response.responseText);
						if (Ext.isEmpty(response.data)) {
							TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgNoClassifaction);
						}
						this.processResponse(data.scientificName, response, index);
					}
				,	failure: function(result){
						TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgFailure);
					}
			});
		}
	
	,	lookupRow: function(index){
			var index = this.store.find("processed", false, index);
			if(index == -1){
				this.task.delay(500); 
				return;
			}	
			var data = this.store.getAt(index).data;
			data.processed = true;
			Ext.Ajax.request({
					scope: this
				,	url:'resources/api/get.php'	
				,	params: {
							name: data.scientificName
						,	cmd: 'taxagrid'
						,	rkey: this.primaryCombo.getValue()
						,	skey: this.secondaryCombo.getValue()		
					}
				,	success: function(response){
						var response = Ext.decode(response.responseText);
						this.processResponse(data.scientificName,response,index);
						this.lookupRow(index);
					}
				,	failure: function(result){
						TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgFailure);
					}	
			});
		}

	,	processResponse: function(name,response, index){
			if(response.success){
				if(response.data != null){
					if(!Ext.isEmpty(response.data)){
						 response.data["class_"] = response.data["class"];
						this.updateRowData(name, response.data, index);
					} else {
						this.updateUnfoundData(name,index);
					}
				} else {
					this.updateUnfoundData(name,index);
				}
			} else{
				TaxonTagger.Notice.msg(this.msgNoticeTitle, this.msgFailure);
			}		
		}
	
	,	updateRowData: function(name, data, index){
			var rec = this.store.getAt(index);
			rec.set('taxonID', data.taxonID);
			//rec.set('scientificName', name);
			rec.set('genus', data.genus);
			rec.set('accordingTo', data.datasetName);
			rec.set('family', data.family);
			rec.set('class_', data.class_);
			rec.set('order', data.order);
			rec.set('phylum', data.phylum);
			rec.set('kingdom', data.kingdom);
			if(data.isSynonym){
				rec.set('acceptedName', data.higherTaxon);
			}
			rec.set('isSynonym', data.isSynonym);
			rec.set('processed', true);
			rec.set('found', true);
			rec.commit();
			this.store.commitChanges();
		}

	,	updateComment: function( commentPanel, a ) {
			var data = this.getSelectionModel().getSelected().data;
			var index = TaxonTagger.docStore.findExact('scientificName', data.scientificName);
			var rec = TaxonTagger.docStore.getAt(index);
			rec.set('comment', commentPanel.txtComment.getValue());
			rec.commit();
			TaxonTagger.docStore.commitChanges();
			Ext.getCmp('list-delimited').loadList();
		}

	,	updateUnfoundData: function(name, index){
			var rec = this.store.getAt(index);
			rec.set('processed', true);
			rec.set('found', false);
			rec.commit();
			this.store.commitChanges();
		}

});